home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1999 May / Macworld (1999-05).dmg / Updaters / SpriteWorld 2.2.1 Update / Source Updates / SpriteLayer.c < prev    next >
Text File  |  1999-02-15  |  16KB  |  617 lines

  1. ///--------------------------------------------------------------------------------------
  2. //    SpriteLayer.c
  3. //
  4. //    Portions are copyright: © 1991-94 Tony Myles, All rights reserved worldwide.
  5. //
  6. //    Description:    implementation of the sprite layers
  7. ///--------------------------------------------------------------------------------------
  8.  
  9.  
  10. #ifndef __SWCOMMON__
  11. #include "SWCommonHeaders.h"
  12. #endif
  13.  
  14. #ifndef __MEMORY__
  15. #include <Memory.h>
  16. #endif
  17.  
  18. #ifndef __SPRITEWORLDUTILS__
  19. #include "SpriteWorldUtils.h"
  20. #endif
  21.  
  22. #ifndef __SPRITEWORLD__
  23. #include "SpriteWorld.h"
  24. #endif
  25.  
  26. #ifndef __SPRITELAYER__
  27. #include "SpriteLayer.h"
  28. #endif
  29.  
  30. #ifndef __SPRITE__
  31. #include "Sprite.h"
  32. #endif
  33.  
  34.  
  35.  
  36. ///--------------------------------------------------------------------------------------
  37. //    SWCreateSpriteLayer
  38. ///--------------------------------------------------------------------------------------
  39.  
  40. SW_FUNC OSErr SWCreateSpriteLayer(
  41.     SpriteLayerPtr *spriteLayerP)
  42. {
  43.     OSErr err;
  44.     SpriteLayerPtr tempSpriteLayerP;
  45.  
  46.     err = noErr;
  47.     *spriteLayerP = NULL;
  48.  
  49.     tempSpriteLayerP = (SpriteLayerPtr)NewPtrClear((Size)sizeof(SpriteLayerRec));
  50.  
  51.     if (tempSpriteLayerP != NULL)
  52.     {
  53.         tempSpriteLayerP->tileLayer = 10;
  54.         tempSpriteLayerP->isPaused = false;
  55.         
  56.         *spriteLayerP = tempSpriteLayerP;
  57.     }
  58.     else
  59.     {
  60.         err = MemError();
  61.     }
  62.  
  63.     SWSetStickyIfError( err );
  64.     return err;
  65. }
  66.  
  67.  
  68. ///--------------------------------------------------------------------------------------
  69. //    SWDisposeSpriteLayer
  70. ///--------------------------------------------------------------------------------------
  71.  
  72. SW_FUNC void SWDisposeSpriteLayer(
  73.     SpriteLayerPtr *spriteLayerPP)
  74. {
  75.     SpriteLayerPtr    spriteLayerP = *spriteLayerPP;
  76.     
  77.     if (spriteLayerP != NULL)
  78.     {
  79.         DisposePtr((Ptr)spriteLayerP);
  80.         *spriteLayerPP = NULL;
  81.     }
  82. }
  83.  
  84.  
  85. ///--------------------------------------------------------------------------------------
  86. //    SWAddSprite
  87. ///--------------------------------------------------------------------------------------
  88.  
  89. SW_FUNC OSErr SWAddSprite(
  90.     SpriteLayerPtr spriteLayerP,
  91.     SpritePtr newSpriteP)
  92. {
  93.     SpritePtr        tailSpriteP = spriteLayerP->tailSpriteP;
  94.     OSErr            err = noErr;
  95.     
  96.     SW_ASSERT(spriteLayerP != NULL);
  97.     SW_ASSERT(newSpriteP != NULL);
  98.     
  99.     if (newSpriteP->parentSpriteLayerP != NULL)
  100.         err = kSpriteAlreadyInLayer;
  101.     
  102.     if (err == noErr)
  103.     {
  104.             // attach the new sprite to the end of the list
  105.             // or make it the head if the list is empty.
  106.         if (tailSpriteP != NULL)
  107.             tailSpriteP->nextSpriteP = newSpriteP;
  108.         else
  109.             spriteLayerP->headSpriteP = newSpriteP;
  110.  
  111.             // link up the new sprite in both directions
  112.         newSpriteP->prevSpriteP = tailSpriteP;
  113.         newSpriteP->nextSpriteP = NULL;
  114.  
  115.             // make the new sprite the tail
  116.         spriteLayerP->tailSpriteP = newSpriteP;
  117.         
  118.             // mark the sprite to be drawn, in case the sprite changed tile layers
  119.         newSpriteP->needsToBeDrawn = true;
  120.  
  121.             // Store the parentSpriteLayer in the Sprite
  122.         newSpriteP->parentSpriteLayerP = spriteLayerP;
  123.     }
  124.     
  125.     SWSetStickyIfError( err );
  126.     return err;
  127. }
  128.  
  129.  
  130. ///--------------------------------------------------------------------------------------
  131. //    SWRemoveSprite
  132. ///--------------------------------------------------------------------------------------
  133.  
  134. SW_FUNC OSErr SWRemoveSprite(
  135.     SpritePtr oldSpriteP)
  136. {
  137.     SpriteLayerPtr    spriteLayerP;
  138.     OSErr            err = noErr;
  139.     
  140.     SW_ASSERT(oldSpriteP != NULL);
  141.     
  142.     spriteLayerP = oldSpriteP->parentSpriteLayerP;
  143.     if (spriteLayerP == NULL)
  144.         err = kBadParameterErr;
  145.     
  146.     if (err == noErr)
  147.     {
  148.             // is this not the tail sprite?
  149.         if (oldSpriteP->nextSpriteP != NULL)
  150.         {
  151.                 // link the next sprite to the prev sprite
  152.             oldSpriteP->nextSpriteP->prevSpriteP = oldSpriteP->prevSpriteP;
  153.         }
  154.         else
  155.         {
  156.                 // make the prev sprite the tail
  157.             spriteLayerP->tailSpriteP = oldSpriteP->prevSpriteP;
  158.         }
  159.  
  160.             // is this not the head sprite?
  161.         if (oldSpriteP->prevSpriteP != NULL)
  162.         {
  163.                 // link the prev sprite to the next sprite
  164.             oldSpriteP->prevSpriteP->nextSpriteP = oldSpriteP->nextSpriteP;
  165.         }
  166.         else
  167.         {
  168.                 // make the next sprite the first sprite
  169.             spriteLayerP->headSpriteP = oldSpriteP->nextSpriteP;
  170.         }
  171.         
  172.         oldSpriteP->parentSpriteLayerP = NULL;
  173.     }
  174.     
  175.     SWSetStickyIfError( err );
  176.     return err;
  177. }
  178.  
  179.  
  180. ///--------------------------------------------------------------------------------------
  181. //    SWRemoveAllSpritesFromLayer
  182. ///--------------------------------------------------------------------------------------
  183.  
  184. SW_FUNC void SWRemoveAllSpritesFromLayer(
  185.     SpriteLayerPtr srcSpriteLayerP)
  186. {
  187.     SpritePtr curSpriteP;
  188.     
  189.     SW_ASSERT(srcSpriteLayerP != NULL);
  190.  
  191.     while ((curSpriteP = SWGetNextSprite(srcSpriteLayerP, NULL)) != NULL)
  192.     {
  193.         SWRemoveSprite(curSpriteP);
  194.     }
  195. }
  196.  
  197.  
  198. ///--------------------------------------------------------------------------------------
  199. //    SWDisposeAllSpritesInLayer
  200. ///--------------------------------------------------------------------------------------
  201.  
  202. SW_FUNC void SWDisposeAllSpritesInLayer(
  203.     SpriteLayerPtr spriteLayerP)
  204. {
  205.     SpritePtr    curSpriteP, nextSpriteP;
  206.     
  207.     SW_ASSERT(spriteLayerP != NULL);
  208.     
  209.     curSpriteP = spriteLayerP->headSpriteP;
  210.     
  211.         // iterate through the sprites in this layer
  212.     while (curSpriteP != NULL)
  213.     {            
  214.         nextSpriteP = curSpriteP->nextSpriteP;
  215.         
  216.         SWRemoveSprite(curSpriteP);
  217.         SWDisposeSprite(&curSpriteP);
  218.         
  219.         curSpriteP = nextSpriteP;
  220.     }
  221. }
  222.  
  223.  
  224. ///--------------------------------------------------------------------------------------
  225. // SWCountNumSpritesInLayer
  226. ///--------------------------------------------------------------------------------------
  227.  
  228. SW_FUNC short SWCountNumSpritesInLayer(
  229.     SpriteLayerPtr spriteLayerP)
  230. {
  231.     SpritePtr        curSpriteP;
  232.     short            numSprites = 0;
  233.     
  234.     SW_ASSERT(spriteLayerP != NULL);
  235.     
  236.     curSpriteP = spriteLayerP->headSpriteP;
  237.     
  238.         // iterate through the sprites in this layer
  239.     while (curSpriteP != NULL)
  240.     {            
  241.         numSprites++;
  242.         curSpriteP = curSpriteP->nextSpriteP;
  243.     }
  244.  
  245.     return numSprites;
  246. }
  247.  
  248.  
  249. ///--------------------------------------------------------------------------------------
  250. //    SWSwapSprite
  251. ///--------------------------------------------------------------------------------------
  252.  
  253. SW_FUNC OSErr SWSwapSprite(
  254.     SpritePtr srcSpriteP,
  255.     SpritePtr dstSpriteP)
  256. {
  257.     SpriteLayerPtr        spriteLayerP;
  258.     register SpritePtr    swapSpriteP;
  259.     OSErr                err = noErr;
  260.     
  261.     SW_ASSERT(srcSpriteP != NULL && dstSpriteP != NULL);
  262.     
  263.     spriteLayerP = srcSpriteP->parentSpriteLayerP;
  264.     if (spriteLayerP != dstSpriteP->parentSpriteLayerP || spriteLayerP == NULL)
  265.     {
  266.         err = kBadParameterErr;
  267.         SWSetStickyIfError( err );
  268.         return err;
  269.     }
  270.     
  271.         // adjacent Sprites are a special case
  272.         
  273.     if ( srcSpriteP->nextSpriteP == dstSpriteP ||
  274.         dstSpriteP->nextSpriteP == srcSpriteP )
  275.     {
  276.         if ( srcSpriteP->nextSpriteP == dstSpriteP )
  277.         {
  278.             if ( srcSpriteP->prevSpriteP != NULL )
  279.                 (srcSpriteP->prevSpriteP)->nextSpriteP = dstSpriteP;
  280.             if ( dstSpriteP->nextSpriteP != NULL )
  281.                 (dstSpriteP->nextSpriteP)->prevSpriteP = srcSpriteP;
  282.             
  283.             dstSpriteP->prevSpriteP = srcSpriteP->prevSpriteP;
  284.             srcSpriteP->nextSpriteP = dstSpriteP->nextSpriteP;
  285.             
  286.             dstSpriteP->nextSpriteP = srcSpriteP;
  287.             srcSpriteP->prevSpriteP = dstSpriteP;
  288.         }
  289.         else
  290.         {
  291.             if ( dstSpriteP->prevSpriteP != NULL )
  292.                 (dstSpriteP->prevSpriteP)->nextSpriteP = srcSpriteP;
  293.             if ( srcSpriteP->nextSpriteP != NULL )
  294.                 (srcSpriteP->nextSpriteP)->prevSpriteP = dstSpriteP;
  295.             
  296.             srcSpriteP->prevSpriteP = dstSpriteP->prevSpriteP;
  297.             dstSpriteP->nextSpriteP = srcSpriteP->nextSpriteP;
  298.             
  299.             srcSpriteP->nextSpriteP = dstSpriteP;
  300.             dstSpriteP->prevSpriteP = srcSpriteP;
  301.         }
  302.     }
  303.     else
  304.     {
  305.         if ( srcSpriteP->prevSpriteP != NULL && dstSpriteP->prevSpriteP != NULL )
  306.         {
  307.             swapSpriteP = (srcSpriteP->prevSpriteP)->nextSpriteP;
  308.             (srcSpriteP->prevSpriteP)->nextSpriteP = 
  309.                     (dstSpriteP->prevSpriteP)->nextSpriteP;
  310.             (dstSpriteP->prevSpriteP)->nextSpriteP = swapSpriteP;
  311.         }
  312.         if ( srcSpriteP->nextSpriteP != NULL && dstSpriteP->nextSpriteP != NULL )
  313.         {
  314.             swapSpriteP = (srcSpriteP->nextSpriteP)->prevSpriteP;
  315.             (srcSpriteP->nextSpriteP)->prevSpriteP = 
  316.                     (dstSpriteP->nextSpriteP)->prevSpriteP;
  317.             (dstSpriteP->nextSpriteP)->prevSpriteP = swapSpriteP;
  318.         }
  319.         
  320.         swapSpriteP = srcSpriteP->nextSpriteP;
  321.         srcSpriteP->nextSpriteP = dstSpriteP->nextSpriteP;
  322.         dstSpriteP->nextSpriteP = swapSpriteP;
  323.  
  324.         swapSpriteP = srcSpriteP->prevSpriteP;
  325.         srcSpriteP->prevSpriteP = dstSpriteP->prevSpriteP;
  326.         dstSpriteP->prevSpriteP = swapSpriteP;
  327.     }
  328.  
  329.  
  330.     if (srcSpriteP->nextSpriteP == NULL)
  331.     {
  332.         spriteLayerP->tailSpriteP = srcSpriteP;
  333.     }
  334.     else if (srcSpriteP->prevSpriteP == NULL)
  335.     {
  336.         spriteLayerP->headSpriteP = srcSpriteP;
  337.     }
  338.  
  339.     if (dstSpriteP->nextSpriteP == NULL)
  340.     {
  341.         spriteLayerP->tailSpriteP = dstSpriteP;
  342.     }
  343.     else if (dstSpriteP->prevSpriteP == NULL)
  344.     {
  345.         spriteLayerP->headSpriteP = dstSpriteP;
  346.     }
  347.     
  348.     return noErr;
  349. }
  350.  
  351.  
  352. ///--------------------------------------------------------------------------------------
  353. //    SWInsertSpriteAfterSprite
  354. ///--------------------------------------------------------------------------------------
  355.  
  356. SW_FUNC OSErr SWInsertSpriteAfterSprite(
  357.     SpritePtr newSpriteP,
  358.     SpritePtr dstSpriteP)
  359. {
  360.     SpriteLayerPtr    spriteLayerP;
  361.     OSErr            err = noErr;
  362.     
  363.     SW_ASSERT(newSpriteP != NULL && dstSpriteP != NULL);
  364.     
  365.     spriteLayerP = dstSpriteP->parentSpriteLayerP;
  366.     if (newSpriteP->parentSpriteLayerP != NULL)
  367.         err = kSpriteAlreadyInLayer;
  368.     
  369.     if (err == noErr)
  370.     {
  371.         if ( dstSpriteP->nextSpriteP != NULL )
  372.             (dstSpriteP->nextSpriteP)->prevSpriteP = newSpriteP;
  373.         
  374.         newSpriteP->nextSpriteP = dstSpriteP->nextSpriteP;
  375.         dstSpriteP->nextSpriteP = newSpriteP;
  376.         newSpriteP->prevSpriteP = dstSpriteP;
  377.         
  378.         if (newSpriteP->nextSpriteP == NULL)
  379.         {
  380.             spriteLayerP->tailSpriteP = newSpriteP;
  381.         }
  382.         
  383.             // mark the sprite to be drawn, in case the sprite changed tile layers
  384.         newSpriteP->needsToBeDrawn = true;
  385.         
  386.         newSpriteP->parentSpriteLayerP = spriteLayerP;
  387.     }
  388.     
  389.     SWSetStickyIfError( err );
  390.     return err;
  391. }
  392.  
  393.  
  394. ///--------------------------------------------------------------------------------------
  395. //    SWInsertSpriteBeforeSprite
  396. ///--------------------------------------------------------------------------------------
  397.  
  398. SW_FUNC OSErr SWInsertSpriteBeforeSprite(
  399.     SpritePtr newSpriteP,
  400.     SpritePtr dstSpriteP)
  401. {
  402.     SpriteLayerPtr    spriteLayerP;
  403.     OSErr            err = noErr;
  404.     
  405.     SW_ASSERT(newSpriteP != NULL && dstSpriteP != NULL);
  406.     
  407.     spriteLayerP = dstSpriteP->parentSpriteLayerP;
  408.     if (newSpriteP->parentSpriteLayerP != NULL)
  409.         err = kSpriteAlreadyInLayer;
  410.     
  411.     if (err == noErr)
  412.     {
  413.         if ( dstSpriteP->prevSpriteP != NULL )
  414.             (dstSpriteP->prevSpriteP)->nextSpriteP = newSpriteP;
  415.         
  416.         newSpriteP->prevSpriteP = dstSpriteP->prevSpriteP;
  417.         dstSpriteP->prevSpriteP = newSpriteP;
  418.         newSpriteP->nextSpriteP = dstSpriteP;
  419.         
  420.         if (newSpriteP->prevSpriteP == NULL)
  421.         {
  422.             spriteLayerP->headSpriteP = newSpriteP;
  423.         }
  424.         
  425.             // mark the sprite to be drawn, in case the sprite changed tile layers
  426.         newSpriteP->needsToBeDrawn = true;
  427.         
  428.         newSpriteP->parentSpriteLayerP = spriteLayerP;
  429.     }
  430.     
  431.     SWSetStickyIfError( err );
  432.     return err;
  433. }
  434.  
  435.  
  436. ///--------------------------------------------------------------------------------------
  437. //    SWGetNextSprite
  438. ///--------------------------------------------------------------------------------------
  439.  
  440. SW_FUNC SpritePtr SWGetNextSprite(
  441.     SpriteLayerPtr spriteLayerP,
  442.     SpritePtr curSpriteP)
  443. {
  444.     SW_ASSERT(spriteLayerP != NULL);
  445.     
  446.     return (curSpriteP == NULL) ? spriteLayerP->headSpriteP : curSpriteP->nextSpriteP;
  447. }
  448.  
  449.  
  450. ///--------------------------------------------------------------------------------------
  451. //    SWLockSpriteLayer
  452. ///--------------------------------------------------------------------------------------
  453.  
  454. SW_FUNC void SWLockSpriteLayer(
  455.     SpriteLayerPtr spriteLayerP)
  456. {
  457.     SpritePtr curSpriteP;
  458.     
  459.     SW_ASSERT(spriteLayerP != NULL);
  460.  
  461.     curSpriteP = spriteLayerP->headSpriteP;
  462.  
  463.     while (curSpriteP != NULL)
  464.     {
  465.         SWLockSprite(curSpriteP);
  466.  
  467.         curSpriteP = curSpriteP->nextSpriteP;
  468.     }
  469. }
  470.  
  471.  
  472. ///--------------------------------------------------------------------------------------
  473. //    SWUnlockSpriteLayer
  474. ///--------------------------------------------------------------------------------------
  475.  
  476. SW_FUNC void SWUnlockSpriteLayer(
  477.     SpriteLayerPtr spriteLayerP)
  478. {
  479.     SpritePtr curSpriteP;
  480.     
  481.     SW_ASSERT(spriteLayerP != NULL);
  482.  
  483.     curSpriteP = spriteLayerP->headSpriteP;
  484.  
  485.     while (curSpriteP != NULL)
  486.     {
  487.         SWUnlockSprite(curSpriteP);
  488.  
  489.         curSpriteP = curSpriteP->nextSpriteP;
  490.     }
  491. }
  492.  
  493.  
  494. ///--------------------------------------------------------------------------------------
  495. //    SWCollideSpriteLayer
  496. ///--------------------------------------------------------------------------------------
  497.  
  498. SW_FUNC void SWCollideSpriteLayer(
  499.     SpriteWorldPtr    spriteWorldP,
  500.     SpriteLayerPtr srcSpriteLayerP,
  501.     SpriteLayerPtr dstSpriteLayerP)
  502. {
  503.     SpritePtr srcSpriteP, nextSrcSpriteP;
  504.     SpritePtr dstSpriteP, nextDstSpriteP;
  505.     Rect sectRect;
  506.     
  507.     SW_ASSERT(spriteWorldP != NULL);
  508.     SW_ASSERT(srcSpriteLayerP != NULL && dstSpriteLayerP != NULL);
  509.     
  510.         // Don't check for collisions unless the frame has been processed!
  511.     if (!spriteWorldP->frameHasOccurred)
  512.         return;
  513.  
  514.     srcSpriteP = srcSpriteLayerP->headSpriteP;
  515.  
  516.     while (srcSpriteP != NULL)
  517.     {
  518.         dstSpriteP = dstSpriteLayerP->headSpriteP;
  519.         nextSrcSpriteP = srcSpriteP->nextSpriteP;
  520.  
  521.         while (dstSpriteP != NULL)
  522.         {
  523.             nextDstSpriteP = dstSpriteP->nextSpriteP;
  524.  
  525.             if (srcSpriteP != dstSpriteP)
  526.             {
  527.                     // are the sprite’s rectangles overlapping?
  528.                 if ((srcSpriteP->destFrameRect.top < dstSpriteP->destFrameRect.bottom) &&
  529.                     (srcSpriteP->destFrameRect.bottom > dstSpriteP->destFrameRect.top) &&
  530.                     (srcSpriteP->destFrameRect.left < dstSpriteP->destFrameRect.right) &&
  531.                     (srcSpriteP->destFrameRect.right > dstSpriteP->destFrameRect.left))
  532.                 {
  533.                         // call the source sprite’s collision routine
  534.                     if (srcSpriteP->spriteCollideProc != NULL)
  535.                     {
  536.                         sectRect.left =
  537.                             SW_MAX(srcSpriteP->destFrameRect.left, dstSpriteP->destFrameRect.left);
  538.                         sectRect.top =
  539.                             SW_MAX(srcSpriteP->destFrameRect.top, dstSpriteP->destFrameRect.top);
  540.                         sectRect.right =
  541.                             SW_MIN(srcSpriteP->destFrameRect.right, dstSpriteP->destFrameRect.right);
  542.                         sectRect.bottom =
  543.                             SW_MIN(srcSpriteP->destFrameRect.bottom, dstSpriteP->destFrameRect.bottom);
  544.  
  545.                         (*srcSpriteP->spriteCollideProc)(srcSpriteP, dstSpriteP, §Rect);
  546.                     }
  547.                 }
  548.             }
  549.             
  550.                 // If the nextDstSpriteP has been removed, we must start over again
  551.             if (nextDstSpriteP != NULL && nextDstSpriteP->spriteRemoval != kSWDontRemoveSprite)
  552.                 dstSpriteP = dstSpriteLayerP->headSpriteP;
  553.             else
  554.                 dstSpriteP = nextDstSpriteP;
  555.         }
  556.         
  557.             // If the nextSrcSpriteP has been removed, we must start over again
  558.         if (nextSrcSpriteP != NULL && nextSrcSpriteP->spriteRemoval != kSWDontRemoveSprite)
  559.             srcSpriteP = srcSpriteLayerP->headSpriteP;
  560.         else
  561.             srcSpriteP = nextSrcSpriteP;
  562.     }
  563. }
  564.  
  565.  
  566. ///--------------------------------------------------------------------------------------
  567. //    SWPauseSpriteLayer
  568. ///--------------------------------------------------------------------------------------
  569.  
  570. SW_FUNC void SWPauseSpriteLayer(
  571.     SpriteLayerPtr    spriteLayerP)
  572. {
  573.     SW_ASSERT(spriteLayerP != NULL);
  574.     
  575.     spriteLayerP->isPaused = true;
  576. }
  577.  
  578.  
  579. ///--------------------------------------------------------------------------------------
  580. //    SWUnpauseSpriteLayer
  581. ///--------------------------------------------------------------------------------------
  582.  
  583. SW_FUNC void SWUnpauseSpriteLayer(
  584.     SpriteLayerPtr    spriteLayerP)
  585. {
  586.     SW_ASSERT(spriteLayerP != NULL);
  587.     
  588.     spriteLayerP->isPaused = false;
  589. }
  590.  
  591.  
  592. ///--------------------------------------------------------------------------------------
  593. //    SWFindSpriteByPoint
  594. ///--------------------------------------------------------------------------------------
  595.  
  596. SW_FUNC SpritePtr SWFindSpriteByPoint(
  597.     SpriteLayerPtr spriteLayerP,
  598.     SpritePtr startSpriteP,
  599.     Point testPoint)
  600. {
  601.     SpritePtr curSpriteP;
  602.     
  603.     SW_ASSERT(spriteLayerP != NULL);
  604.  
  605.     curSpriteP = (startSpriteP == NULL) ? spriteLayerP->tailSpriteP : startSpriteP;
  606.  
  607.         // note that we traverse the sprites in reverse order
  608.         // since this will make the most sense if we are
  609.         // looking for a sprite that was clicked
  610.     while ((curSpriteP != NULL) && !SWIsPointInSprite(curSpriteP, testPoint))
  611.     {
  612.         curSpriteP = curSpriteP->prevSpriteP;
  613.     }
  614.  
  615.     return curSpriteP;
  616. }
  617.